using System;
using System.Collections.Generic;
using System.Text;

namespace PlayFab
{
    /// <summary>
    /// Error codes returned by PlayFabAPIs
    /// </summary>
    public enum PlayFabErrorCode
    {
        Unknown = 1,
        ConnectionError = 2,
        JsonParseError = 3,
        <% for(var i=0; i<errorList.length-1; i++) { var errorProps = errors[errorList[i]] %><%- errorProps.name %> = <%- errorProps.id %>,
        <% } %><% var errorProps = errors[errorList[errorList.length-1]] %><%- errorProps.name %> = <%- errorProps.id %>
    }

    public class PlayFabError
    {
        public string ApiEndpoint;
        public int HttpCode;
        public string HttpStatus;
        public PlayFabErrorCode Error;
        public string ErrorMessage;
        public Dictionary<string, List<string>> ErrorDetails;
        public object CustomData;

        public override string ToString()
        {
            return GenerateErrorReport();
        }

        [ThreadStatic]
        private static StringBuilder _tempSb;
        /// <summary>
        /// This converts the PlayFabError into a human readable string describing the error.
        /// If error is not found, it will return the http code, status, and error
        /// </summary>
        /// <returns>A description of the error that we just incur.</returns>
        public string GenerateErrorReport()
        {
            if (_tempSb == null)
                _tempSb = new StringBuilder();
            _tempSb.Length = 0;
            if (String.IsNullOrEmpty(ErrorMessage))
            {
                _tempSb.Append(ApiEndpoint).Append(": ").Append("Http Code: ").Append(HttpCode.ToString()).Append("\nHttp Status: ").Append(HttpStatus).Append("\nError: ").Append(Error.ToString()).Append("\n");
            }
            else
            {
                _tempSb.Append(ApiEndpoint).Append(": ").Append(ErrorMessage);
            }

            if (ErrorDetails != null)
                foreach (var pair in ErrorDetails)
                    foreach (var msg in pair.Value)
                        _tempSb.Append("\n").Append(pair.Key).Append(": ").Append(msg);
            return _tempSb.ToString();
        }
    }

    public class PlayFabException : Exception
    {
        public readonly PlayFabExceptionCode Code;
        public PlayFabException(PlayFabExceptionCode code, string message) : base(message)
        {
            Code = code;
        }
    }

    public enum PlayFabExceptionCode
    {
        AuthContextRequired,
        BuildError,
        DeveloperKeyNotSet,
        EntityTokenNotSet,
        NotLoggedIn,
        TitleNotSet,
    }
}
